 package com.gxa.weixing.pc.realm;


 import com.gxa.weixing.core.common.ExceptionCode;
 import com.gxa.weixing.core.exception.BusinessException;
 import com.gxa.weixing.core.pojo.Manager;
 import com.gxa.weixing.core.pojo.ManagerModel;
 import com.gxa.weixing.core.pojo.Menu;
 import com.gxa.weixing.core.pojo.Role;
 import com.gxa.weixing.pc.service.ManagerService;
 import lombok.SneakyThrows;
 import org.apache.shiro.authc.*;
 import org.apache.shiro.authz.AuthorizationInfo;
 import org.apache.shiro.authz.SimpleAuthorizationInfo;
 import org.apache.shiro.realm.AuthorizingRealm;
 import org.apache.shiro.subject.PrincipalCollection;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.util.StringUtils;

 /**
  * 如何设计一个自定义的Realm，通过继承AuthorizingRealm
  * 重写两个方法：
  *      doGetAuthorizationInfo(验证)
  *      doGetAuthenticationInfo(授权)
  * @ClassName AdminRealm
  * @Author: ws
  * @date 2021/12/23 14:09
  */
 public class ManagerRealm extends AuthorizingRealm {

     @Autowired
     ManagerService managerService;

     @Override
     protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
         //获取登录手机号
         String phone = (String) principalCollection.getPrimaryPrincipal();
         //System.out.println("managerRealm 中授权得到phone: "+phone);

         // 调用业务层方法，获取用户的角色和权限信息
         ManagerModel managerModel = managerService.getManagerMenus(phone);
         //添加角色和权限
         SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
         for (Role role : managerModel.getRoleList()) {
             //添加角色
             //System.out.println("role.getRoleName(): "+role.getRoleName());
             info.addRole(role.getRoleName());
             //添加权限
             for (Menu menu : role.getMenuList()) {
                 //System.out.println("menu.getMenuName(): "+menu.getMenuName());
                 info.addStringPermission(menu.getMenuName());
             }
         }
         return info;

         // 设置假数据
         /*SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
         info.addRole("admin");
         info.addStringPermission("user:add");
         info.addStringPermission("user:delete");
         return info;*/
     }


     @SneakyThrows
     @Override
     protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

         // 通过spring自带的字符串工具StringUtils 进行数据校验
         // 用UsernamePasswordToken
         // token.getPrincipal() 获取用户名username
         System.out.println("token.getPrincipal(): "+token.getPrincipal());
         if (StringUtils.isEmpty(token.getPrincipal())) {
             /*try {
                 throw new Exception("AuthenticationToken 不能为空");
             } catch (Exception e) {
                 e.printStackTrace();
             }*/

            // 如果校验不成功，返回null，触发shiro自定义的异常
             return null;
         }

         //获取用户信息
         String phone = token.getPrincipal().toString();
         Manager byPhone = managerService.getByPhone(phone);
         if (byPhone == null) {
             //这里返回后会报出对应异常
             return null;
         } else if (byPhone.getManagerState() == 0) {
             // 用户存在但是,用户状态异常
             // throw null;
             throw new LockedAccountException("账户已被冻结");
         } else {
             // 这里验证authenticationToken和simpleAuthenticationInfo的信息
             // SimpleAuthenticationInfo对象封装了Realm和用户验证的方法
             // 需要提供 username,password,realm
             SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(phone, byPhone.getManagerPwd(), getName());
             return info;
         }

         // 测试假数据返回
         /*SimpleAuthenticationInfo info = new SimpleAuthenticationInfo("admin", "123456", getName());
         return info;*/
     }
 }
